var map, vectors, vfeatures, gridPoints, selectedFeature, select, popup, store, storeError,gyFeatures,spFeatures,varId;
var urlFeatures = null;
var urlInfractions = null;

function handler(request) {
	document.getElementById("textJson").value = request.responseText;
}

function processRequest() {
	var request = OpenLayers.Request.POST({
		url : "GeoinformaticsService",
		data : document.getElementById("output").value,
		callback : handler
	});
	handler(request);
}

function init() {
	map = new OpenLayers.Map('map');

	urlFeatures = "http://localhost:8080/geoinfo-server/faces/GeomDomainFeatures.jsp?domain="
			+ document.getElementById("domain").value;

	urlInfractions = "http://localhost:8080/geoinfo-server/faces/InfractionFeatures.jsp?domain="
			+ document.getElementById("domain").value;

	gridPoints = new OpenLayers.Layer.Vector("Grid result", {
		isBaseLayer : true,
		name : "Grid points",
		styleMap : new OpenLayers.StyleMap({
			pointRadius : 1,
			strokeColor : "#31B404",
			strokeWidth : 1,
			fillOpacity : 1,
			fillColor : "#31B404",
			graphicName : "square"
		})
	});

	vectors = new OpenLayers.Layer.Vector("Elementos");

	vfeatures = new OpenLayers.Layer.Vector("infraciones", {
		isBaseLayer : false,
		name : "infraciones",
		styleMap : new OpenLayers.StyleMap({
			pointRadius : 5,
			strokeColor : "#FF0040",
			strokeWidth : 1,
			fillOpacity : 1,
			fillColor : "#FF0040",
			graphicName : "x"
		})
	});
	
	gyFeatures= new OpenLayers.Layer.Vector("GreenYaoFeatures", {
		isBaseLayer : false,
		name : "gyFeatures",
		styleMap : new OpenLayers.StyleMap({
			pointRadius : 4,
			strokeColor : "#000080",
			strokeWidth : 2,
			fillOpacity : 0,
			fillColor : "#000080",
			graphicName : "circle"
		})
	});
	
	spFeatures= new OpenLayers.Layer.Vector("spaghettiFeatures", {
		isBaseLayer : false,
		name : "spFeatures",
		styleMap : new OpenLayers.StyleMap({
			pointRadius : 3,
			strokeColor : "#66FF00",
			strokeWidth : 4,
			fillOpacity : 0.5,
			fillColor : "#66FF00",
			graphicName : "circle"
		})
	});

	map.addLayers([spFeatures,gyFeatures,vectors, gridPoints, vfeatures]);

	map.addControl(new OpenLayers.Control.MousePosition());

	map.addControl(new OpenLayers.Control.EditingToolbar(vectors));

	map.addControl(new OpenLayers.Control.LayerSwitcher());

	map
			.addControl(new OpenLayers.Control.ZoomBox(
					{
						title : "Zoom box: Selecting it you can zoom on an area by clicking and dragging."
					}));

	var snap = new OpenLayers.Control.Snapping({
		layer : vectors,
		targets : [ {
			layer : gridPoints,
			tolerance : 15
		} ]
	});

	snap.activate();

	var options = {
		clickout : true,
		hover : true,
		toggle : true,
		clickFeature : serialize,
		onSelect : serialize
	};

	select = new OpenLayers.Control.SelectFeature([ vectors, vfeatures ],
			options);

	map.addControl(select);

	select.activate();

	map.setCenter(new OpenLayers.LonLat(0, 0), 1);

	document.getElementById("output").value = ("{\"type\": \"Operation\",\"name\": \"retrieveGridDomain\",\"properties\": {\"user\": \"geoinfouser\",\"domainId\": \""+ document.getElementById("domain").value + "\"}}");

	processRequest();

	deserializeJsonMap();
}

function deleteFeature() {
	selectedFeature.popup.destroy();
	selectedFeature.destroy();
}

function deserializeJsonMap() {
	var element = document.getElementById('textJson');
	var geojson = new OpenLayers.Format.GeoJSON();
	var features = geojson.read(element.value);
	var s = element.value;
	var valido = 0;
	var valiDbFeat = 0;
	var validGy = 0;
	var validSp = 0;
	valido = s.indexOf("ResultDomainGrid");
	valiDbFeat = s.indexOf("resultGeometry");
	validGy=s.indexOf("GreenYaoAdjustmentData");
	validSp=s.indexOf("spaghettiFeaturesData");
	var bounds;
	if (features) {
		if (features.constructor != Array) {
			features = [ features ];
		}
		for ( var i = 0; i < features.length; ++i) {
			if (!bounds) {
				bounds = features[i].geometry.getBounds();
			} else {
				bounds.extend(features[i].geometry.getBounds());
			}

		}
		if (valido == -1 && valiDbFeat == -1) {
			vectors.addFeatures(features);
		} else if (valido != -1 && valiDbFeat == -1) {
			gridPoints.destroyFeatures();
			gridPoints.addFeatures(features);
		} else if (valido == -1 && valiDbFeat != -1) {
			vectors.destroyFeatures();
			vectors.addFeatures(features);
			store.load();
			storeError.load();
		}if (validGy != -1) {
			gyFeatures.destroyFeatures();
			gyFeatures.addFeatures(features);
		}if (validSp != -1) {
			spFeatures.destroyFeatures();
			spFeatures.addFeatures(features);
		}
		
		map.zoomToExtent(bounds);
		var plural = (features.length > 1) ? 's' : '';
		element.value = features.length + ' feature' + plural + ' added';
	} else {
		element.value = 'Bad input geoJson';
	}
}

function serialize(feature) {
	// feature.id=document.getElementById("domain").value;
	selectedFeature = feature;
	// second argument for pretty printing (geojson only)
	var pretty = document.getElementById("prettyPrint").checked;
	var geojson = new OpenLayers.Format.GeoJSON();
	var str = geojson.write(feature, pretty);
	// not a good idea in general, just for this demo
	str = str.replace(/,/g, ', ');
	// this.popup = new OpenLayers.Popup.FramedCloud("featurePopup",
	// selectedFeature.geometry.getBounds().getCenterLonLat(),
	// new OpenLayers.Size(100,100),
	// "<input type=\"button\" value=\"add to DataBase\" style=\"border: #08088A
	// 1px solid; font-family: Verdana; font-size: 9px; background-color:
	// #DEDEDE; font-weight: bold \" onclick=\"processRequest();\" /><br><input
	// type=\"button\" value=\"delete from memory\" style=\"border: #08088A 1px
	// solid; font-family: Verdana; font-size: 9px; background-color: #DEDEDE;
	// font-weight: bold \" onclick=\"deleteFeature();\" />",
	// null, true, null);
	// selectedFeature.popup = this.popup;
	// map.addPopup(this.popup);
	document.getElementById('output').value = "{\"type\": \"operation\",\"name\": \"addFeature\",\"domainId\":"
			+ document.getElementById("domain").value
			+ ",\"features\": ["
			+ str + "]}";
}

function onFeatureUnselect(feature) {
	map.removePopup(feature.popup);
	feature.popup.destroy();
	feature.popup = null;
}

function onPopupClose(evt) {
	select.unselect(selectedFeature);
}

Ext.onReady(function() {

	// NOTE: This is an example showing simple state management. During
	// development,
	// it is generally best to disable state management as dynamically-generated
	// ids
	// can change across page loads, leading to unpredictable results. The
	// developer
	// should ensure that stable state ids are set for stateful components in
	// real apps.

	// create map panel
	mapPanel = new GeoExt.MapPanel({
		title : "Map",
		region : "center",
		height : 400,
		width : 600,
		map : map
	});

	// create feature store, binding it to the vector layer
	store = new GeoExt.data.FeatureStore({
		layer : vectors,
		fields : [ {
			name : 'id',
			type : 'string'
		}, {
			name : 'result',
			type : 'string'
		} ],
		proxy : new GeoExt.data.ProtocolProxy({
			protocol : new OpenLayers.Protocol.HTTP({
				url : urlFeatures,
				format : new OpenLayers.Format.GeoJSON()
			})
		}),
		autoLoad : true
	});

	storeError = new GeoExt.data.FeatureStore({
		layer : vfeatures,
		fields : [ {
			name : 'id',
			type : 'string'
		}, {
			name : 'result',
			type : 'string'
		} ],
		proxy : new GeoExt.data.ProtocolProxy({
			protocol : new OpenLayers.Protocol.HTTP({
				url : urlInfractions,
				format : new OpenLayers.Format.GeoJSON()
			})
		}),
		autoLoad : true
	});
	
	storeSpaghetti = new GeoExt.data.FeatureStore({
		layer : spFeatures,
		fields : [ {
			name : 'id',
			type : 'string'
		}, {
			name : 'result',
			type : 'string'
		} ],
		autoLoad : true
	});

	// create grid panel configured with feature store
	gridPanel = new Ext.grid.GridPanel({
		title : "Elementos",
		region : "east",
		store : store,
		width : 300,
		columns : [ {
			header : "Id",
			width : 50,
			dataIndex : "id"
		}, {
			header : "geom",
			width : 150,
			dataIndex : "result"
		} ],
		sm : new GeoExt.grid.FeatureSelectionModel()
	});

	gridPanelErrors = new Ext.grid.GridPanel({
		title : "Infracciones",
		region : "east",
		store : storeError,
		width : 300,
		columns : [ {
			header : "tipo",
			width : 200,
			dataIndex : "id"
		}, {
			header : "descripcion",
			width : 600,
			dataIndex : "result"
		} ],
		sm : new GeoExt.grid.FeatureSelectionModel()
	});
	
	gridPanelSpaghetti= new Ext.grid.GridPanel({
		title : "Spaghetti",
		region : "east",
		store : storeSpaghetti,
		width : 300,
		columns : [ {
			header : "id",
			width : 40,
			dataIndex : "id"
		}, {
			header : "descripcion",
			width : 250,
			dataIndex : "result"
		} ],
		sm : new GeoExt.grid.FeatureSelectionModel()
	});

	 var borrarForm = new Ext.FormPanel({
	        labelWidth: 15, // label settings here cascade unless overridden
	        id:'borrarFormId',
	        url:'save-form.php',
	        frame:true,
	        title: 'Borrar elementos',
	        bodyStyle:'padding:5px 5px 0',
	        width: 220,
	        defaults: {width: 220},
	        buttons: [{
	            text: 'borrar seleccionado',
	            handler:deleteSelected
	        },{
	            text: 'recargar',
	            handler:deserializeJsonMap
	        }]
	    });
	 
	 
	 var GreenYaoForm = new Ext.FormPanel({
	        labelWidth: 15, // label settings here cascade unless overridden
	        url:'save-form.php',
	        frame:true,
	        title: 'Ajustar por Green-Yao',
	        bodyStyle:'padding:5px 5px 0',
	        width: 220,
	        defaults: {width: 220},
	        defaultType: 'textfield',
	        buttons: [{
	            text: 'ajustar',
	            handler:retrieveGreenYao	
	        },{
	            text: 'zoom',
	            handler:deserializeJsonMap		
	        }]
	    });
	 
	 var rejillaForm = new Ext.FormPanel({
	        labelWidth: 15, // label settings here cascade unless overridden
	        frame:true,
	        title: 'Opciones de rejilla',
	        bodyStyle:'padding:5px 5px 0',
	        width: 220,
	        defaults: {width: 220},
	        defaultType: 'textfield',
	        buttons: [{
	            text: 'cargar',
	            handler:retrieveGrid	
	        },{
	            text: 'zoom',
	            handler:deserializeJsonMap		
	        }]
	    });
	 

	 
	 var spaghettiForm = new Ext.FormPanel({
	        labelWidth: 15, // label settings here cascade unless overridden
	        url:'save-form.php',
	        frame:true,
	        title: 'Modelo Espaghetti',
	        bodyStyle:'padding:5px 5px 0',
	        width: 220,
	        defaults: {width: 220},
	        defaultType: 'textfield',
	        buttons: [{
	            text: 'calcular',
	            handler:retrieveSpaghetti	
	        },{
	            text: 'zoom',
	            handler:deserializeJsonMap		
	        }]
	    });
	 
	 
	    
	 var editionForm = new Ext.FormPanel({
	        labelWidth: 15, // label settings here cascade unless overridden
	        url:'save-form.php',
	        frame:true,
	        title: 'Editar geometria',
	        bodyStyle:'padding:2px 2px 0',
	        width: 220,
	        defaults: {width: 220},
	        defaultType: 'textfield',
	        buttons: [{
	            text: 'agregar seleccionado',
	            handler:processRequest	
	        },{
	            text: 'recargar',
	            handler:deserializeJsonMap		
	        }]
	    });
	 
	    function retrieveGreenYao()
	    {
	  	document.getElementById("output").value = ("{\"type\": \"Operation\",\"name\": \"greenYaoAdjustment\",\"properties\": {\"user\": \"geoinfouser\",\"domainId\": \""+ document.getElementById("domain").value + "\"}}");
	  	processRequest();
	    }
	 
	
	    function deleteSelected()
	    {
	    	var featureToDel=document.getElementById("output").value;
	    	featureToDel=featureToDel.replace("addFeature", "deleteFeature");
	    	document.getElementById("output").value=featureToDel;
	    	processRequest();
	    }
	 
	    
	    function retrieveSpaghetti()
	    {
	  	document.getElementById("output").value = ("{\"type\": \"Operation\",\"name\": \"retrieveSpaghettiFeatures\",\"properties\": {\"user\": \"geoinfouser\",\"domainId\": \""+ document.getElementById("domain").value + "\"}}");
	  	processRequest();
	    }
	 
	    function retrieveGrid()
	    {
	  	document.getElementById("output").value =("{\"type\": \"Operation\",\"name\": \"retrieveGridDomain\",\"properties\": {\"user\": \"geoinfouser\",\"domainId\": \""+ document.getElementById("domain").value + "\"}}");
	  	processRequest();
	    }
	    
	Ext.state.Manager.setProvider(new Ext.state.CookieProvider());

	var viewport = new Ext.Viewport({
		layout : 'border',
		items : [ {
			region : 'east',
			title : 'Informacion',
			collapsible : true,
			split : true,
			width : 250, // give east and west regions a width
			minSize : 175,
			maxSize : 250,
			margins : '0 5 0 0',
			layout : 'fit', // specify layout manager for items
			items : // this TabPanel is wrapped by another Panel so the title
			// will be applied
			new Ext.TabPanel({
				border : false, // already wrapped so don't add another border
				activeTab : 1, // second tab initially active
				tabPosition : 'bottom',
				items : [ gridPanelErrors, gridPanel,gridPanelSpaghetti]
			})
		}, {
			region : 'west',
			id : 'west-panel', // see Ext.getCmp() below
			title : 'Tools',
			split : true,
			width : 222,
			minSize : 175,
			maxSize : 222,
			collapsible : true,
			margins : '0 0 0 5',
			layout : {
				type : 'accordion',
				animate : true
			},
			items : [ {
				title : 'Herramientas',
				border : false,
				items: [rejillaForm,editionForm,borrarForm,GreenYaoForm,spaghettiForm],
				iconCls : 'settings'
			}, {
				contentEl : 'west',
				title : 'Comandos',
				border : false,
				iconCls : 'nav' // see the HEAD section for style used
			} , {
				title : 'Leyenda',
				border : false,
				html : '<img src="icons/leyenda.png" alt="leyenda" />',
				iconCls : 'nav' // see the HEAD section for style used
			} ]
		},
		// in this instance the TabPanel is not wrapped by another panel
		// since no title is needed, this Panel is added directly
		// as a Container
		new Ext.TabPanel({
			region : 'center', // a center region is ALWAYS required for border
			// layout
			deferredRender : false,
			activeTab : 0, // first tab initially active
			items : [ mapPanel ]
		}) ]
	});
	// get a reference to the HTML element with id "hideit" and add a click
	// listener to it
	Ext.get("hideit").on('click', function() {
		// get a reference to the Panel that was created with id = 'west-panel'
		var w = Ext.getCmp('west-panel');
		// expand or collapse that Panel based on its collapsed property state
		w.collapsed ? w.expand() : w.collapse();
	});
});
